package cn.itcast.nems.base.web.controller.b;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.itcast.ic.common.bean.Page;
import cn.itcast.ic.common.exception.v2.BizExceptionProducer;
import cn.itcast.nems.base.api.ClazzApi;
import cn.itcast.nems.base.dao.entity.E2Clazz;
import cn.itcast.nems.base.dao.mapper.E2ClazzMapper;
import cn.itcast.nems.base.dto.ClazzDTO;
import cn.itcast.nems.base.dto.ClazzQueryDTO;
import cn.itcast.nems.base.dto.E2ClazzDto;
import cn.itcast.nems.base.web.util.ClazzWebUtil;
import cn.itcast.nems.base.web.vo.ClazzPriceCalculateVO;
import cn.itcast.nems.base.web.vo.ClazzQueryVO;
import cn.itcast.nems.common.PageQueryModel;
import cn.itcast.nems.common.constant.PaymentTypeEum;
import cn.itcast.nems.common.enumeration.NemsErrorBodyEnum;
import cn.itcast.nems.common.web.vo.BasePageRequest;
import cn.itcast.nems.discount.api.DiscountApi;
import cn.itcast.nems.discount.dto.DiscountSummaryDTO;
import cn.itcast.nems.product.scheduler.TuitionFeeService;
import cn.itcast.nems.studentrecord.service.DiscountCalculator;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController("bClazzController")
@RequestMapping("/b/clazz")
@RequiredArgsConstructor
@Slf4j
public class ClazzController {

    private final E2ClazzMapper e2ClazzMapper;
    private final ClazzApi clazzApi;
    private final TuitionFeeService tuitionFeeService;
    private final DiscountApi discountApi;

    @RequestMapping("/form/search/{text}")
    public ResponseEntity<List<E2ClazzDto>> formSearch(
            @PathVariable String text,
            @RequestParam(value = "upgrade", required = false) Boolean upgrade
    ) {
        return ResponseEntity.ok(
                e2ClazzMapper.selectList(
                                new QueryWrapper<E2Clazz>()
                                        .lambda()
                                        .like(E2Clazz::getClazzName, text)
                                        .eq(
                                                upgrade != null,
                                                E2Clazz::getUpgradeable,
                                                upgrade == null ? null : !upgrade
                                        )
                                        .orderByDesc(E2Clazz::getStartDate)
                                        .last("limit 50")
                        )
                        .stream()
                        .map(this::mapToDto)
                        .collect(Collectors.toList())
        );
    }
    /**
     * <p>
     * 根据班级ID查询班级详情
     * </p>
     *
     * @author zhouwei
     * @since 2024/4/11 1:44 PM
     **/
    @GetMapping("/{clazz_id}")
    public ResponseEntity<ClazzDTO> getById(@PathVariable("clazz_id") Integer clazzId) {
        return ResponseEntity.ok().body(clazzApi.queryByClassId(clazzId)) ;
    }

    /**
     * 根据班级ID和支付方式获取学费金额
     *
     * @param clazzId
     * @param paymentType
     * @return
     */
    @GetMapping("/tuition_fee")
    public ResponseEntity<String> getTuition(@RequestParam(name = "clazz_id") Integer clazzId,
                                             @RequestParam(name = "payment_type", defaultValue = "FIRSTPAYMENT") String paymentType) {
        BigDecimal tuitionFee = tuitionFeeService.findTuition(clazzId, paymentType);
        String fee = Objects.nonNull(tuitionFee) ? new DecimalFormat("0.00").format(tuitionFee) : null;
        return ResponseEntity.ok().body(fee);
    }

    /**
     * 根据班级ID和支付方式获取学费金额
     *
     * @param calculateVO
     * @return
     */
    @PostMapping("/calculate")
    public ResponseEntity<String> calculate(@RequestBody ClazzPriceCalculateVO calculateVO) {
        log.info("【根据班级ID和支付方式获取学费金额】请求参数：{}", JSON.toJSONString(calculateVO));
        Assert.isTrue(Objects.nonNull(calculateVO) && Objects.nonNull(calculateVO.getClazzId()),
                BizExceptionProducer.produce(NemsErrorBodyEnum.PARAM_EMPTY, "班级ID"));
        List<DiscountSummaryDTO> list = null;
        if (CollectionUtil.isNotEmpty(calculateVO.getDiscountIds())) {
            list = calculateVO.getDiscountIds().stream().map(this.discountApi::getSummaryById).toList();
        }
        BigDecimal tuitionFee = tuitionFeeService.findTuition(calculateVO.getClazzId(),
                Objects.nonNull(calculateVO.getPaymentType()) ? calculateVO.getPaymentType() : PaymentTypeEum.FIRSTPAYMENT.name());
        int clazzPrice = tuitionFee.multiply(BigDecimal.valueOf(100)).intValue();
        int result = clazzPrice - new DiscountCalculator(list).calculate(clazzPrice, clazzPrice);
        String fee = new DecimalFormat("0.00").format(BigDecimal.valueOf(result).divide(BigDecimal.valueOf(100)));
        return ResponseEntity.ok().body(fee);
    }

    private E2ClazzDto mapToDto(E2Clazz e2Clazz) {
        E2ClazzDto e2ClazzDto = new E2ClazzDto();
        e2ClazzDto.setClazzName(e2Clazz.getClazzName());
        e2ClazzDto.setClazzId(e2Clazz.getClazzId());
        return e2ClazzDto;
    }

    /**
     * 根据条件分页查询班级信息
     *
     * @param params 请求参数
     * @return 班级分页信息
     */
    @PostMapping("/page/list")
    public ResponseEntity<Page<ClazzDTO>> query(@RequestBody BasePageRequest<ClazzQueryVO> params) {
        params.convert();
        PageQueryModel<ClazzQueryDTO> queryModel = new PageQueryModel<>(
                params.getPageNumber(),
                params.getPageSize(),
                ClazzWebUtil.convert(params.getCondition() == null ? new ClazzQueryVO() : params.getCondition())
        );
        return ResponseEntity.ok(clazzApi.queryPageList(queryModel));
    }

}
